package com.aliang.shopping.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.aliang.shopping.common.Result;
import com.aliang.shopping.common.ResultCodeEnum;
import com.aliang.shopping.contact.ResultMsgContact;
import com.aliang.shopping.contact.SqlColumnConstant;
import com.aliang.shopping.exception.DataException;
import com.aliang.shopping.log.annotation.OperateLog;
import com.aliang.shopping.log.enums.OperateType;
import com.aliang.shopping.model.converter.AddressConverter;
import com.aliang.shopping.model.dto.address.AddressInsertDTO;
import com.aliang.shopping.model.dto.address.AddressUpdateDTO;
import com.aliang.shopping.model.dto.common.UpdateStatusDTO;
import com.aliang.shopping.model.po.Address;
import com.aliang.shopping.model.vo.address.AddressVO;
import com.aliang.shopping.security.PreventRepeatSubmit;
import com.aliang.shopping.security.auth.UserHolder;
import com.aliang.shopping.service.AddressService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.Collections;
import java.util.List;

@RestController
@RequestMapping("/address")
@AllArgsConstructor
public class AddressController {

    private final AddressService addressService;
    private final AddressConverter addressConverter;

    /**
     * 地址插入
     *
     * @param insertDTO
     * @return
     */
    @PostMapping("/insert")
    @ApiOperation("地址插入")
    @PreventRepeatSubmit
    @OperateLog(title = "地址插入", type = OperateType.INSERT)
    public Result<String> insertAddress(@RequestBody AddressInsertDTO insertDTO) {
        //必要字段校验
        if (BeanUtil.hasNullField(insertDTO) ||
                StrUtil.hasBlank(insertDTO.getAreaAddress(), insertDTO.getDetailAddress(), insertDTO.getContact(), insertDTO.getPhone())) {
            throw new DataException(ResultCodeEnum.DATA_LACK);
        }
        //验证手机号码
        if (!Validator.isMobile(insertDTO.getPhone())) {
            throw new DataException(ResultCodeEnum.PHONE_NOT_LEGAL);
        }
        //转换数据
        Address address = this.addressConverter.toPoByInsertDTO(insertDTO);
        //获取当前登录用户对象Id
        Long userId = UserHolder.getUserId();
        //设置创建人Id
        address.setUserId(userId);
        //获取最大的排序值
        Integer maxOrderNum = this.addressService.getObj(
                new QueryWrapper<Address>()
                        .select("max(order_num)")
                        .eq(SqlColumnConstant.USER_ID, userId),
                o -> (Integer) o
        );
        //如果最大值不为空，设置排序值加1;
        if (ObjectUtil.isNotNull(maxOrderNum)) {
            address.setOrderNum(maxOrderNum + 1);
        }
        //插入数据
        this.addressService.save(address);
        return Result.ok(ResultMsgContact.INSERT_SUCCESS);
    }

    /**
     * 地址删除
     *
     * @param ids
     * @return
     */
    @DeleteMapping("/del")
    @ApiOperation("地址删除")
    @PreventRepeatSubmit
    @OperateLog(title = "地址删除", type = OperateType.DELETE)
    public Result<String> delAddress(@RequestBody List<Long> ids) {
        this.addressService.removeByIds(ids);
        return Result.ok(ResultMsgContact.DELETE_SUCCESS);
    }

    /**
     * 地址更改
     *
     * @param updateDTO
     * @return
     */
    @PutMapping("/update")
    @ApiOperation("地址更改")
    @PreventRepeatSubmit
    @OperateLog(title = "地址更改", type = OperateType.UPDATE)
    public Result<String> updateAddress(@RequestBody AddressUpdateDTO updateDTO) {
        //必要字段校验
        if (BeanUtil.hasNullField(updateDTO) ||
                StrUtil.hasBlank(updateDTO.getAreaAddress(), updateDTO.getDetailAddress(), updateDTO.getContact(), updateDTO.getPhone())) {
            throw new DataException(ResultCodeEnum.DATA_LACK);
        }
        //验证手机号码
        if (!Validator.isMobile(updateDTO.getPhone())) {
            throw new DataException(ResultCodeEnum.PHONE_NOT_LEGAL);
        }
        //转换数据
        Address address = this.addressConverter.toPoByUpdateDTO(updateDTO);
        //更新数据
        boolean b = this.addressService.updateById(address);
        return Result.ok(ResultMsgContact.UPDATE_SUCCESS);
    }

    /**
     * 地址排序更改
     *
     * @param updateDTO
     * @return
     */
    @PutMapping("/update_address_order_num")
    @ApiOperation("地址排序更改")
    @PreventRepeatSubmit
    @OperateLog(title = "地址排序更改", type = OperateType.UPDATE)
    public Result<String> updateAddressOrderNum(@RequestBody List<UpdateStatusDTO> updateDTO) {
        //必要字段校验
        if (BeanUtil.isEmpty(updateDTO)) {
            throw new DataException(ResultCodeEnum.DATA_LACK);
        }
        //获取当前用户Id
        Long userId = UserHolder.getUserId();
        //转换数据
        List<Address> staticDTOList = this.addressConverter.toPoByUpdateStaticDTOList(updateDTO);
        // 加层保险，设置用户Id
       staticDTOList.forEach(address -> address.setUserId(userId));
        //更新数据
        boolean b = this.addressService.updateBatchById(staticDTOList);
        return b ? Result.ok(ResultMsgContact.UPDATE_SUCCESS) : Result.fail(ResultMsgContact.UPDATE_FAIL_SUCCESS);
    }


    /**
     * 设置地址首选状态
     *
     * @return
     */
    @PutMapping("/set_address_first_static/{addressId}")
    @ApiOperation("地址首选状态更改")
    @PreventRepeatSubmit
    @OperateLog(title = "设置地址首选状态", type = OperateType.UPDATE_STATUS)
    public Result<String> setAddressFirstStatic(@PathVariable("addressId") Long addressId) {
        //必要字段校验
        if (BeanUtil.isEmpty(addressId)) {
            throw new DataException(ResultCodeEnum.DATA_LACK);
        }
        //获取当前登录用户Id
        Long userId = UserHolder.getUserId();
        //根据用户Id查询已有的首选的地址Id
        Address one = this.addressService.getOne(new LambdaQueryWrapper<Address>()
                .select(Address::getId)
                .eq(Address::getUserId, userId)
                .eq(Address::getFirstStatus, SqlColumnConstant.STATUS_OK));
        //有首选地址，修改首选状态
        if (ObjectUtil.isNotEmpty(one)) {
            //修改状态为非首选
            one.setFirstStatus(SqlColumnConstant.STATUS_FAIL);
            //更新数据
            this.addressService.updateById(one);
        }
        //封装首选状态地址对象
        Address address = new Address();
        address.setId(addressId);
        address.setUserId(userId);
        address.setFirstStatus(SqlColumnConstant.STATUS_OK);
        //更新要修改的数据
        this.addressService.updateById(address);
        return Result.ok(ResultMsgContact.UPDATE_SUCCESS);
    }

    /**
     * 获取全部地址信息
     */
    @GetMapping("/getAddressList")
    @ApiOperation("获取全部地址信息")
    public Result<List<AddressVO>> getAddressList() {
        //获取登录用户Id
        Long userId = UserHolder.getUserId();
        //根据用户Id查询地址列表，排序升序，更新时间倒序
        List<AddressVO> list = this.addressService.getAddressList(userId);
        //没有数据，返回空集合
        if (list.isEmpty()) {
            return Result.ok(Collections.emptyList());
        }
        //返回数据
        return Result.ok(list);
    }
}
